package org.finesys.common.websocket.handler;

import static org.finesys.common.constants.CacheConstants.PROJECT_OAUTH_ACCESS;

import java.security.Principal;
import java.util.List;

import org.finesys.common.websocket.entity.WebSocketUser;
import org.finesys.common.websocket.support.WebSocketHolder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.NonNull;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 用于传输从webSocket客户端接收的消息
 */
@Slf4j
@RequiredArgsConstructor
public class WebSocketClientInboundChannel implements ChannelInterceptor {
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public Message<?> preSend(@NonNull Message<?> message, @NonNull MessageChannel channel) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
        if (accessor != null && accessor.getCommand() != null) {
            switch (accessor.getCommand()) {
                case CONNECT:
                    List<String> tokens = accessor.getNativeHeader("access_token");
                    if (tokens != null && !tokens.isEmpty()) {
                        Principal principal = verifyToken(tokens.get(0));
                        if (principal != null) {
                            accessor.setUser(principal);
                            return message;
                        }
                    }
            }
        }
        return message;
    }

    /**
     * 校验用户信息是否合法
     */
    private Principal verifyToken(String token) {
        String key = buildKey(token);
        if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
            OAuth2Authorization authorization = (OAuth2Authorization) redisTemplate.opsForValue().get(key);
            String userName="";
            if(authorization!=null){
                userName=authorization.getPrincipalName();    
            }
            WebSocketUser webSocketUser = new WebSocketUser();
            webSocketUser.setUserName(userName);
            webSocketUser.setToken(token);
            return webSocketUser;
        }
        return null;
    }

    private String buildKey(String token) {
        return String.format("%s::%s", PROJECT_OAUTH_ACCESS, token);
    }

    @Override
    public void postSend(@NonNull Message<?> message,@NonNull MessageChannel channel, boolean sent) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
        if (accessor.getCommand() == null) {
            return;
        }
        //获取用户信息
        String userName = WebSocketHolder.getUserName(accessor);
        //这里的sessionId和accountId对应HttpSessionIdHandshakeInterceptor拦截器的存放key
        switch (accessor.getCommand()) {
            case CONNECT:
                log.info("============>当前登录用户{}, 建立websocket连接", userName);
                break;
            case CONNECTED://链接成功
                break;
            case DISCONNECT:
                log.info("============>当前登录用户{}, 断开websocket连接", userName);
                break;
            case ERROR:
                log.error("============>当前登录用户{},websocket连接错误", userName);
                break;
            default:
        }
    }


}
